import 'dart:io';
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:path/path.dart' as path;
import '../constants/app_constants.dart';

/// 应用工具类
/// Application utility class
class AppUtils {
  // 私有构造函数，防止实例化
  // Private constructor to prevent instantiation
  AppUtils._();

  // ==================== 日期时间工具 Date Time Utils ====================
  
  /// 格式化日期时间
  /// Format date time
  static String formatDateTime(DateTime dateTime, {String? format}) {
    format ??= 'yyyy-MM-dd HH:mm';
    return DateFormat(format).format(dateTime);
  }
  
  /// 格式化日期
  /// Format date
  static String formatDate(DateTime dateTime, {String? format}) {
    format ??= 'yyyy-MM-dd';
    return DateFormat(format).format(dateTime);
  }
  
  /// 格式化时间
  /// Format time
  static String formatTime(DateTime dateTime, {String? format}) {
    format ??= 'HH:mm';
    return DateFormat(format).format(dateTime);
  }
  
  /// 格式化短日期（MM/dd）
  /// Format short date (MM/dd)
  static String formatShortDate(DateTime dateTime) {
    return DateFormat('MM/dd').format(dateTime);
  }
  
  /// 获取相对时间描述
  /// Get relative time description
  static String getRelativeTime(DateTime dateTime) {
    final now = DateTime.now();
    final difference = now.difference(dateTime);
    
    if (difference.inDays > 0) {
      if (difference.inDays == 1) {
        return '昨天';
      } else if (difference.inDays < 7) {
        return '${difference.inDays}天前';
      } else if (difference.inDays < 30) {
        final weeks = (difference.inDays / 7).floor();
        return '${weeks}周前';
      } else if (difference.inDays < 365) {
        final months = (difference.inDays / 30).floor();
        return '${months}个月前';
      } else {
        final years = (difference.inDays / 365).floor();
        return '${years}年前';
      }
    } else if (difference.inHours > 0) {
      return '${difference.inHours}小时前';
    } else if (difference.inMinutes > 0) {
      return '${difference.inMinutes}分钟前';
    } else {
      return '刚刚';
    }
  }
  
  /// 判断是否为今天
  /// Check if date is today
  static bool isToday(DateTime dateTime) {
    final now = DateTime.now();
    return dateTime.year == now.year &&
           dateTime.month == now.month &&
           dateTime.day == now.day;
  }
  
  /// 判断是否为昨天
  /// Check if date is yesterday
  static bool isYesterday(DateTime dateTime) {
    final yesterday = DateTime.now().subtract(const Duration(days: 1));
    return dateTime.year == yesterday.year &&
           dateTime.month == yesterday.month &&
           dateTime.day == yesterday.day;
  }
  
  /// 判断是否为本周
  /// Check if date is this week
  static bool isThisWeek(DateTime dateTime) {
    final now = DateTime.now();
    final startOfWeek = now.subtract(Duration(days: now.weekday - 1));
    final endOfWeek = startOfWeek.add(const Duration(days: 6));
    
    return dateTime.isAfter(startOfWeek.subtract(const Duration(days: 1))) &&
           dateTime.isBefore(endOfWeek.add(const Duration(days: 1)));
  }
  
  /// 判断是否为本月
  /// Check if date is this month
  static bool isThisMonth(DateTime dateTime) {
    final now = DateTime.now();
    return dateTime.year == now.year && dateTime.month == now.month;
  }
  
  /// 获取月份的第一天
  /// Get first day of month
  static DateTime getFirstDayOfMonth(DateTime dateTime) {
    return DateTime(dateTime.year, dateTime.month, 1);
  }
  
  /// 获取月份的最后一天
  /// Get last day of month
  static DateTime getLastDayOfMonth(DateTime dateTime) {
    return DateTime(dateTime.year, dateTime.month + 1, 0);
  }
  
  /// 获取周的第一天（周一）
  /// Get first day of week (Monday)
  static DateTime getFirstDayOfWeek(DateTime dateTime) {
    return dateTime.subtract(Duration(days: dateTime.weekday - 1));
  }
  
  /// 获取周的最后一天（周日）
  /// Get last day of week (Sunday)
  static DateTime getLastDayOfWeek(DateTime dateTime) {
    return dateTime.add(Duration(days: 7 - dateTime.weekday));
  }
  
  // ==================== 文件工具 File Utils ====================
  
  /// 获取文件大小（字节）
  /// Get file size in bytes
  static Future<int> getFileSize(String filePath) async {
    try {
      final file = File(filePath);
      if (await file.exists()) {
        return await file.length();
      }
      return 0;
    } catch (e) {
      return 0;
    }
  }
  
  /// 格式化文件大小
  /// Format file size
  static String formatFileSize(int bytes) {
    if (bytes < 1024) {
      return '${bytes}B';
    } else if (bytes < 1024 * 1024) {
      return '${(bytes / 1024).toStringAsFixed(1)}KB';
    } else if (bytes < 1024 * 1024 * 1024) {
      return '${(bytes / (1024 * 1024)).toStringAsFixed(1)}MB';
    } else {
      return '${(bytes / (1024 * 1024 * 1024)).toStringAsFixed(1)}GB';
    }
  }
  
  /// 检查文件是否存在
  /// Check if file exists
  static Future<bool> fileExists(String filePath) async {
    try {
      final file = File(filePath);
      return await file.exists();
    } catch (e) {
      return false;
    }
  }
  
  /// 删除文件
  /// Delete file
  static Future<bool> deleteFile(String filePath) async {
    try {
      final file = File(filePath);
      if (await file.exists()) {
        await file.delete();
        return true;
      }
      return false;
    } catch (e) {
      return false;
    }
  }
  
  /// 获取文件扩展名
  /// Get file extension
  static String getFileExtension(String filePath) {
    return path.extension(filePath).toLowerCase();
  }
  
  /// 获取文件名（不含扩展名）
  /// Get file name without extension
  static String getFileNameWithoutExtension(String filePath) {
    return path.basenameWithoutExtension(filePath);
  }
  
  /// 获取文件名（含扩展名）
  /// Get file name with extension
  static String getFileName(String filePath) {
    return path.basename(filePath);
  }
  
  /// 检查是否为图片文件
  /// Check if file is image
  static bool isImageFile(String filePath) {
    final extension = getFileExtension(filePath);
    return AppConstants.supportedImageFormats.contains(extension);
  }
  
  /// 检查是否为音频文件
  /// Check if file is audio
  static bool isAudioFile(String filePath) {
    final extension = getFileExtension(filePath);
    return AppConstants.supportedAudioFormats.contains(extension);
  }
  
  /// 生成唯一文件名
  /// Generate unique file name
  static String generateUniqueFileName(String extension) {
    final timestamp = DateTime.now().millisecondsSinceEpoch;
    final random = Random().nextInt(10000);
    return '${timestamp}_$random$extension';
  }
  
  // ==================== 验证工具 Validation Utils ====================
  
  /// 验证邮箱格式
  /// Validate email format
  static bool isValidEmail(String email) {
    final emailRegex = RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$');
    return emailRegex.hasMatch(email);
  }
  
  /// 验证手机号格式
  /// Validate phone number format
  static bool isValidPhoneNumber(String phoneNumber) {
    final phoneRegex = RegExp(r'^1[3-9]\d{9}$');
    return phoneRegex.hasMatch(phoneNumber);
  }
  
  /// 验证密码强度
  /// Validate password strength
  static bool isStrongPassword(String password) {
    // 至少8位，包含大小写字母、数字和特殊字符
    // At least 8 characters, including uppercase, lowercase, numbers and special characters
    final passwordRegex = RegExp(r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$');
    return passwordRegex.hasMatch(password);
  }
  
  /// 验证字符串是否为空或仅包含空白字符
  /// Validate if string is empty or contains only whitespace
  static bool isEmptyOrWhitespace(String? text) {
    return text == null || text.trim().isEmpty;
  }
  
  /// 验证字符串长度
  /// Validate string length
  static bool isValidLength(String text, {int? minLength, int? maxLength}) {
    final length = text.length;
    if (minLength != null && length < minLength) return false;
    if (maxLength != null && length > maxLength) return false;
    return true;
  }
  
  // ==================== 数字工具 Number Utils ====================
  
  /// 格式化数字（添加千分位分隔符）
  /// Format number with thousand separators
  static String formatNumber(num number) {
    final formatter = NumberFormat('#,###');
    return formatter.format(number);
  }
  
  /// 格式化百分比
  /// Format percentage
  static String formatPercentage(double value, {int decimalPlaces = 1}) {
    return '${(value * 100).toStringAsFixed(decimalPlaces)}%';
  }
  
  /// 限制数字范围
  /// Clamp number within range
  static T clamp<T extends num>(T value, T min, T max) {
    if (value < min) return min;
    if (value > max) return max;
    return value;
  }
  
  /// 生成随机数
  /// Generate random number
  static int randomInt(int min, int max) {
    final random = Random();
    return min + random.nextInt(max - min + 1);
  }
  
  /// 生成随机双精度数
  /// Generate random double
  static double randomDouble(double min, double max) {
    final random = Random();
    return min + random.nextDouble() * (max - min);
  }
  
  // ==================== 颜色工具 Color Utils ====================
  
  /// 将颜色转换为十六进制字符串
  /// Convert color to hex string
  static String colorToHex(Color color) {
    return '#${color.value.toRadixString(16).padLeft(8, '0').substring(2)}';
  }
  
  /// 将十六进制字符串转换为颜色
  /// Convert hex string to color
  static Color? hexToColor(String hex) {
    try {
      hex = hex.replaceAll('#', '');
      if (hex.length == 6) {
        hex = 'FF$hex';
      }
      return Color(int.parse(hex, radix: 16));
    } catch (e) {
      return null;
    }
  }
  
  /// 获取颜色的亮度
  /// Get color brightness
  static double getColorBrightness(Color color) {
    return (0.299 * color.red + 0.587 * color.green + 0.114 * color.blue) / 255;
  }
  
  /// 判断颜色是否为深色
  /// Check if color is dark
  static bool isDarkColor(Color color) {
    return getColorBrightness(color) < 0.5;
  }
  
  /// 获取对比色（黑色或白色）
  /// Get contrast color (black or white)
  static Color getContrastColor(Color color) {
    return isDarkColor(color) ? Colors.white : Colors.black;
  }
  
  // ==================== 字符串工具 String Utils ====================
  
  /// 首字母大写
  /// Capitalize first letter
  static String capitalize(String text) {
    if (text.isEmpty) return text;
    return text[0].toUpperCase() + text.substring(1).toLowerCase();
  }
  
  /// 每个单词首字母大写
  /// Capitalize each word
  static String capitalizeWords(String text) {
    return text.split(' ').map((word) => capitalize(word)).join(' ');
  }
  
  /// 截断文本
  /// Truncate text
  static String truncateText(String text, int maxLength, {String suffix = '...'}) {
    if (text.length <= maxLength) return text;
    return text.substring(0, maxLength - suffix.length) + suffix;
  }
  
  /// 移除HTML标签
  /// Remove HTML tags
  static String removeHtmlTags(String html) {
    final regex = RegExp(r'<[^>]*>');
    return html.replaceAll(regex, '');
  }
  
  /// 生成随机字符串
  /// Generate random string
  static String generateRandomString(int length) {
    const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    final random = Random();
    return String.fromCharCodes(
      Iterable.generate(length, (_) => chars.codeUnitAt(random.nextInt(chars.length))),
    );
  }
  
  /// 生成UUID
  /// Generate UUID
  static String generateUuid() {
    final random = Random();
    final timestamp = DateTime.now().millisecondsSinceEpoch;
    final randomPart = random.nextInt(0xFFFFFF);
    return '${timestamp.toRadixString(16)}-${randomPart.toRadixString(16)}';
  }
  
  // ==================== 设备工具 Device Utils ====================
  
  /// 获取设备类型
  /// Get device type
  static String getDeviceType(BuildContext context) {
    final screenWidth = MediaQuery.of(context).size.width;
    return AppConstants.getDeviceType(screenWidth);
  }
  
  /// 判断是否为平板设备
  /// Check if device is tablet
  static bool isTablet(BuildContext context) {
    return getDeviceType(context) == 'tablet';
  }
  
  /// 判断是否为桌面设备
  /// Check if device is desktop
  static bool isDesktop(BuildContext context) {
    return getDeviceType(context) == 'desktop';
  }
  
  /// 判断是否为手机设备
  /// Check if device is mobile
  static bool isMobile(BuildContext context) {
    return getDeviceType(context) == 'mobile';
  }
  
  /// 获取屏幕尺寸
  /// Get screen size
  static Size getScreenSize(BuildContext context) {
    return MediaQuery.of(context).size;
  }
  
  /// 获取状态栏高度
  /// Get status bar height
  static double getStatusBarHeight(BuildContext context) {
    return MediaQuery.of(context).padding.top;
  }
  
  /// 获取底部安全区域高度
  /// Get bottom safe area height
  static double getBottomSafeAreaHeight(BuildContext context) {
    return MediaQuery.of(context).padding.bottom;
  }
  
  // ==================== 调试工具 Debug Utils ====================
  
  /// 打印调试信息
  /// Print debug information
  static void debugPrint(String message, {String? tag}) {
    if (AppConstants.isDebugMode) {
      final timestamp = DateTime.now().toIso8601String();
      final tagPrefix = tag != null ? '[$tag] ' : '';
      print('[$timestamp] $tagPrefix$message');
    }
  }
  
  /// 打印错误信息
  /// Print error information
  static void debugPrintError(String message, {String? tag, dynamic error, StackTrace? stackTrace}) {
    if (AppConstants.isDebugMode) {
      final timestamp = DateTime.now().toIso8601String();
      final tagPrefix = tag != null ? '[$tag] ' : '';
      print('[$timestamp] ERROR $tagPrefix$message');
      if (error != null) {
        print('Error: $error');
      }
      if (stackTrace != null) {
        print('StackTrace: $stackTrace');
      }
    }
  }
}